<template>
  <div class="upload-file">
    <el-upload
      :action="uploadFileUrl"
      :file-list="uploadFiles"
      :limit="limit"
      :multiple="limit > 1"
      :before-upload="handleBeforeUpload"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :headers="headers"
      class="upload-file-uploader"
      ref="upload">
      <!-- 上传按钮 -->
      <el-button size="mini" type="primary">选取文件</el-button>
      <!-- 上传提示 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        请上传
        <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
        <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("、") }}</b> </template>
        的文件
      </div>
    </el-upload>

    <!-- 文件列表 -->
    <file-list :file-list="fileList" :editable="true" @delete="handleDelete"></file-list>
  </div>
</template>

<script>
import FileList from "./FileList";

import { getToken } from "@/utils/auth";

export default {
  name: "FileUpload",
  components: {
    FileList
  },
  props: {
    // 值
    value: Array,
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 50,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ["bmp", "gif", "jpg", "jpeg", "png", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "rar", "zip", "pdf"]
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    limit: {
      type: Number,
      default: 100,
    }
  },
  model: {
    prop: 'value',
    event: 'input'
  },
  data() {
    return {
      uploadFileUrl: process.env.VUE_APP_BASE_API + "/file/upload",
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      fileList: this.value,
      uploadFiles: [],
      icons: {
        bmp: "picture",
        gif: "picture",
        jpg: "picture",
        jpeg: "picture",
        png: "picture",
        doc: "word",
        docx: "word",
        xls: "excel",
        xlsx: "excel",
        ppt: "powerpoint",
        pptx: "powerpoint",
        txt: "txt",
        rar: "zip",
        zip: "zip",
        pdf: "pdf",
        default: "file"
      }
    };
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    }
  },
  methods: {
    init() {
      const fileList = [];
      this.$lodash.forEach(this.fileList, item => {
        fileList.push({
          uid: item.uid,
          name: item.fileName,
          url: item.filePath
        })
      });
      this.uploadFiles = fileList;
    },
    // 上传前校检格式和大小
    handleBeforeUpload(file) {
      // 校检文件类型
      if (this.fileType && this.fileType.length > 0) {
        const fileExtension = this.getFileExtension(file.name);
        const isTypeOk = this.fileType.some((type) => {
          if (file.type.indexOf(type) > -1) {
            return true;
          }
          if (fileExtension && fileExtension.indexOf(type) > -1) {
            return true;
          }
          return false;
        });
        if (!isTypeOk) {
          this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
          return false;
        }
      }
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize;
        if (!isLt) {
          this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
          return false;
        }
      }
      return true;
    },
    getFileExtension(fileName) {
      return fileName.slice(fileName.lastIndexOf(".") + 1);
    },
    fileIcon(fileName) {
      const fileExtension = this.getFileExtension(fileName);
      return this.icons[fileExtension] || this.icons["default"];
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`只允许上传${this.limit}个文件`);
    },
    // 上传失败
    handleUploadError(err) {
      console.error(err);
      this.$message.error("上传失败, 请重试");
    },
    // 上传成功回调
    handleUploadSuccess(res, file) {
      if (res.code !== 200) {
        this.$message.error(file.name + " 上传失败");
        return;
      }

      const data = res.data;
      this.fileList.push({
        uid: file.uid,
        fileName: data.fileName,
        filePath: data.url
      });
      this.$message.success(file.name + " 上传成功");
      this.$emit("input", this.fileList);
    },
    // 删除文件
    handleDelete(index) {
      const file = this.fileList[index];
      this.$refs.upload.handleRemove(null, file);

      this.fileList.splice(index, 1);
      this.$emit("input", this.fileList);
    },
    clearAll() {
      this.$refs.upload.clearFiles();
      this.uploadFiles = [];
      this.fileList = [];
    }
  },
  watch: {
    value: {
      handler(val) {
        this.fileList = val;
      },
      deep: true
    }
  }
};
</script>

<style scoped lang="scss">
.upload-file-uploader {
  margin-bottom: 5px;

  .el-upload__tip {
    line-height: 22px;
  }
}
</style>
